package multithread.consumerandproducer;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author: zhangrongqing
 * @Date: 2020/5/16 9:05
 */
public class ConsumerAndProducer {

    //模拟生产者消费者消费的东西
    private  Integer count = 0;

    //用锁来保证生产者和消费者之间通信
    private ReentrantLock reentrantLock = new ReentrantLock();
    Condition producerCondition;
    Condition consumerCondition;

    public ConsumerAndProducer() {
        producerCondition = reentrantLock.newCondition();
        consumerCondition = reentrantLock.newCondition();
    }

    public void consumer() {
        reentrantLock.lock();
        if (reentrantLock.isLocked()) {
            try {
                while (count <= 0) {
                    consumerCondition.await();
                }
                //一次消费1个
                count--;
                producerCondition.signalAll();
                System.out.println("消费者消费了1个,剩余：" + count);
                //模拟业务处理时间
                Thread.sleep(1000);
            } catch (Exception e) {
                System.out.println("消费者发生错误" + e);
            } finally {
                reentrantLock.unlock();
            }
        }

    }

    public void producer() {
        reentrantLock.lock();
        if (reentrantLock.isLocked()) {
            try {

                //一次生产3个
                for (int i = 0; i < 3; i++) {
                    while (count >= 5) {
                        System.out.println("生产过剩");
                        producerCondition.await();
                    }
                    count++;
                    System.out.println("生产者生产了1个,剩余：" + count);
//                    Thread.sleep(1000);
                    if (count >= 0) {
                        consumerCondition.signalAll();
                    }
                }
            } catch (Exception e) {
                System.out.println("生产者发生错误" + e);
            } finally {
                reentrantLock.unlock();
            }
        }

    }

    public static void main(String[] args) throws InterruptedException {

        ConsumerAndProducer consumerAndProducer = new ConsumerAndProducer();
        ExecutorService pService = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 10; i++) {
            pService.submit(() -> consumerAndProducer.consumer());
        }

//        Thread.sleep(1000);

        ExecutorService cService = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 10; i++) {
            cService.submit(() -> consumerAndProducer.producer());
        }

        pService.shutdown();
        cService.shutdown();

    }

}
